package org.lizar.controller.staticsrc;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;

import org.lizar.controller.Controller;
import org.lizar.controller.loader.EventLoader;
import org.lizar.exception.LifecycleException;
import org.lizar.ioc.Lifecycle;
import org.lizar.log.Log;
import org.lizar.log.Logger;
import org.lizar.util.Pair;


public class StaticResource implements Lifecycle{
	private static Log log=Logger.newInstance(StaticResource.class);
	
	public  String listen_path;
	
	
	private static StaticResource instance;
	
	
	private StaticResource(){
		
	
	}
	
	private StaticResource(String _listen_path){
		this.listen_path = _listen_path;
	}
	
	public static StaticResource instance(String _listen_path){
		if(instance==null){
			instance=new StaticResource(_listen_path);
		}
		return instance;
	}
	
	@Override
	public void die() throws LifecycleException{
		log.info(this.getClass().getSimpleName()+" stopping");
	}
	
	@Override
	public  void born()throws LifecycleException{
		log.info(this.getClass().getSimpleName()+" starting");
	
	}
	
	
	public static void handle(EventLoader el,String path) {
		path=el.getRealPath(path);
		handle_abs_file(el,path);
	}
	
	public static void handle_abs_file(EventLoader el,String path) {
		HttpServletResponse response=el.response();
		response.setContentType(ContentType.is(el.postfix()));
		response.setCharacterEncoding(Controller.encode_type);
		read_file(el,response.getContentType(),path);
		
	}
	public static void handle_abs_file(EventLoader el,String path,int response_code) {
		HttpServletResponse response=el.response();
		response.setStatus(response_code);
		handle_abs_file(el,path);
	}
	
	private static void response_not_found(EventLoader el,String path){
		el.response().setStatus(HttpServletResponse.SC_NOT_FOUND);
		el.log.error("request:"+el.getRequestPath()+" read failed for read file "+path);
		try {
			el.text(el.getRequestPath()+"404 not found",404);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	
	
	private static void read_file(EventLoader el,String contentType,String path) {
		if(contentType.startsWith("image")){
			read_image(el,path);
		}else{
			read_file(el,path);
		}
	}
	
	private static void read_file(EventLoader el,String path) {
		Pair<Long,List<String>> b=null;
		try {
			b = read(path);
		} catch (FileNotFoundException e) {
			response_not_found(el,path);
			return;
		} catch (IOException e) {
			el.log.error("request:"+el.getRequestPath()+" read failed for read file "+path,e);
			response_not_found(el,path);
			return;
		}
		if(b==null||b.getValue().isEmpty()){
			response_not_found(el,path);
			return;
		}else{
			write(b.getValue(),el);
		}
	}
	
	private static void read_image(EventLoader el,String path) {
		
		File f = new File(path);
		
		if(!f.exists()){
			System.out.println(path);
			response_not_found(el,path);
			return;
		}
		
		BufferedImage image = null;
		try {
			image=ImageIO.read(f);
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			el.write_image(image,el.postfix());
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	

	
	private static long last_modify_time(String path){
		File f=new File(path);
		return f.lastModified();
	}
	
	private static Pair<Long,List<String>> read(String path) throws IOException {
		File f=new File(path);
		FileInputStream in = null;
		in= new FileInputStream(f);
		in.close();
		List<String> list=new LinkedList<String>();
		FileReader filereader = new FileReader(f);
		BufferedReader bufferedReader=new BufferedReader(filereader);
		String str="";
		while((str=bufferedReader.readLine())!=null){
			list.add(str);
		}
		filereader.close();
		bufferedReader.close();
		return new Pair<Long,List<String>>(f.length(),list);
	}
	
	private static Pair<Long,List<String>> read(File f) throws IOException {
		FileInputStream in = null;
		in= new FileInputStream(f);
		int size = in.available();
		in.close();
		List<String> list=new LinkedList<String>();
		FileReader filereader = new FileReader(f);
		BufferedReader bufferedReader=new BufferedReader(filereader);
		String str="";
		while((str=bufferedReader.readLine())!=null){
			list.add(str);
		}
		filereader.close();
		bufferedReader.close();
		return new Pair<Long,List<String>>(new Long(size),list);
	}
	
	
	private static void write(List<String> list,EventLoader el) {
		PrintWriter out  = null;
		try {
			out = el.response().getWriter();
			Iterator<String> itr=list.iterator();
			for(;itr.hasNext();){
				out.write(itr.next());
			}
			out.flush();
		}catch(Exception e){
			el.log.error("Response output stream exception in "+el.getRequestPath(), e);
		}finally{
			if(out != null)out.close();
		}
		
		
		
	}

	@Override
	public void init_property() throws Exception {
		// TODO Auto-generated method stub
		
	}

	

}
